package utils

import (
	comm "com.wangzhumo.lottery/common"
	"com.wangzhumo.lottery/datasource"
	"com.wangzhumo.lottery/models"
	"com.wangzhumo.lottery/services"
	"fmt"
	"log"
)

// PrizeCachePoolNum 返回奖池中对应奖品的剩余数量
func PrizeCachePoolNum(id int) int64 {
	// key
	key := "gift_pool"
	redisConn := datasource.InstanceRedis()

	reply, err := redisConn.Do("HGET", key, id)
	if err != nil {
		log.Println("PrizeCachePoolNum HGET key = ", key, " err = ", err)
		return 0
	} else {
		return comm.GetInt64(reply, 0)
	}
}

// 是否可以发奖
func prizeServerGift(id int) bool {
	key := "gift_pool"
	redisConn := datasource.InstanceRedis()
	// 发奖-数量减少
	reply, err := redisConn.Do("HINCRBY", key, id, -1)
	if err != nil {
		log.Println("prizeServerGift HINCRBY key = ", key, " err = ", err)
		return false
	}
	// 获取操作完之后的值
	num := comm.GetInt64(reply, -1)
	return num >= 0
}

// PrizeGift 发奖，指定的奖品是否还可以发出来奖品
func PrizeGift(id int, leftNum int) bool {
	// 更新数据库，减少奖品的库存
	ok := false
	ok = prizeServerGift(id)

	if ok {
		giftService := services.NewGiftServices()
		rows, err := giftService.DecrLeftNum(id, 1)
		if rows < 1 || err != nil {
			log.Println("prizedata.PrizeGift giftService.DecrLeftNum error=", err, ", rows=", rows)
			// 数据更新失败，不能发奖
			return false
		}
	}
	return ok
}

// ImportCacheCodes 不同编码的优惠券 - 导入
func ImportCacheCodes(id int, code string) bool {
	key := fmt.Sprintf("code_gift_%d", id)
	redisConn := datasource.InstanceRedis()
	// 分割 set 中添加code
	_, err := redisConn.Do("SADD", key, code)
	if err != nil {
		log.Println("prizedata.PrizeGift ImportCacheCodes SADD key = ", key, " error ：", err)
		return false
	}
	return true
}

// ReCacheCodes 重新缓存优惠券的录入
func ReCacheCodes(id int, server services.CodeService) (ok int,fail int) {
	ltCoupon := server.Search(id)
	if ltCoupon == nil || len(ltCoupon) <= 0 {
		log.Println("prizedata.PrizeGift ReCacheCodes Search null")
		return 0,0
	}

	// 获取code
	key := fmt.Sprintf("code_gift_%d", id)
	tempKey := "temp_" + key
	// 正在使用的key不动，避免造成错误
	redisConn := datasource.InstanceRedis()
	for _, coupon := range ltCoupon {
		// 写入
		if coupon.SysStatus == 0 {
			code := coupon.Code
			_, err := redisConn.Do("SADD", tempKey, code)
			if err == nil {
				ok++
			}else{
				fail++
			}
		}
	}
	// 改名字
	_, err := redisConn.Do("RENAME", tempKey, key)
	if err != nil {
		log.Println("prizedata.PrizeGift ReCacheCodes RENAME error : ",err)
		return 0,0
	}
	return
}

// GetCacheCodesNum 获取剩余优惠券的数量
func GetCacheCodesNum(id int, server services.CodeService) (dbNum int,cacheNum int) {
	//db
	ltCoupon := server.Search(id)
	if ltCoupon != nil && len(ltCoupon) > 0 {
		for _, coupon := range ltCoupon {
			if coupon.SysStatus == 0 {
				dbNum++
			}
		}
	}

	//cache
	key := fmt.Sprintf("code_gift_%d", id)
	redisConn := datasource.InstanceRedis()
	// 返回回集合 KEY 的基数(集合中元素的数量)。
	rows, err := redisConn.Do("SCARD",key)
	if err == nil{
		cacheNum = int(comm.GetInt64(rows,0))
	}else{
		log.Println("prizedata.PrizeGift GetCacheCodesNum SCARD error : ",err)
	}
	return
}

// 发奖 - 优惠券 - cache
func prizeServerCodeDiff(id int,server services.CodeService) (code string) {
	key := fmt.Sprintf("code_gift_%d", id)
	redisConn := datasource.InstanceRedis()
	// 移除并返回 集合 中的一个随机元素
	res, err := redisConn.Do("SPOP", key)
	if err != nil {
		log.Println("prizedata.PrizeGift prizeServerCodeDiff SPOP error : ",err)
		return
	}
	code = comm.GetString(res,"")
	if code == "" {
		log.Println("prizedata.PrizeGift prizeServerCodeDiff code null")
		return
	}
	// 此时应该减少数据库里面的数据
	err = server.UpdateByCode(&models.LtCoupon{Code: code, SysStatus: 2, SysUpdated: comm.NowUnix()}, nil)
	if err != nil {
		log.Println("prizedata.PrizeGift prizeServerCodeDiff UpdateByCode error : ",err)
		return
	}
	return
}

// 发奖 - 优惠券 - database
func prizeDbCodeDiff(id int,server services.CodeService) (code string) {
	// 需要加锁
	lockUserKey := 0 - id - 1000000
	LockUser(lockUserKey)
	// 记得解锁
	defer UnLockUser(lockUserKey)

	nextUsingCode := server.NextUsingCode(id, 0)
	if nextUsingCode != nil && nextUsingCode.Id > 0 {
		nextUsingCode.SysStatus = 1
		nextUsingCode.SysUpdated = comm.NowUnix()
		server.Update(nextUsingCode, nil)
	} else {
		log.Println("prize_data.go PrizeCodeDiff error giftId = ", id)
		return ""
	}
	return nextUsingCode.Code
}

// PrizeCodeDiff 发有编号的优惠券
func PrizeCodeDiff(id int, server services.CodeService) string {
	// 需要加锁
	//lockUserKey := 0 - id - 1000000
	//LockUser(lockUserKey)
	//// 记得解锁
	//defer UnLockUser(lockUserKey)
	//
	//nextUsingCode := server.NextUsingCode(id, 0)
	//if nextUsingCode != nil && nextUsingCode.Id > 0 {
	//	nextUsingCode.SysStatus = 1
	//	nextUsingCode.SysUpdated = comm.NowUnix()
	//	server.Update(nextUsingCode, nil)
	//} else {
	//	log.Println("prize_data.go PrizeCodeDiff error giftId = ", id)
	//	return ""
	//}

	return prizeServerCodeDiff(id,server)
}
